home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / utils / console / splitvt-.000 / splitvt- / splitvt-1.6.1 / videomem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-10  |  7.6 KB  |  347 lines

  1.  
  2. /* This file holds the functions for manipulating video memory */
  3.  
  4. #include    <stdio.h>
  5. #include    "video.h"
  6. #include    "terminal.h"
  7.  
  8. /* This function returns a pointer to a video memory area of ints.
  9.    Integers are used to encode both the characters and the flags.
  10.    If this function fails, it should be a fatal error.  Allocated
  11.    memory is not freed if the function fails.
  12.  */
  13.  
  14. int **alloc_video(rows, cols)
  15. int rows;
  16. int cols;
  17. {
  18.     int **videomem;
  19.     int i, j;
  20.  
  21.     /* Allocate row pointers */
  22.     if ( (videomem=(int **)malloc(rows*sizeof(int *))) == NULL )
  23.         return(NULL);
  24.  
  25.     /* Allocate the columns for each row */
  26.     for ( i=0; i<rows; ++i ) {
  27.         if ( (videomem[i]=(int *)malloc(cols*sizeof(int))) == NULL )
  28.             return(NULL);
  29.         for ( j=0; j<cols; ++j )
  30.             videomem[i][j]=0;
  31.     }
  32.     return(videomem);
  33. }
  34.  
  35. /* This function copies an existing window to a new buffer, 
  36.    truncating lines if necessary, and translates the cursor position  */
  37. void copy_video(win, newarea, rows, cols, newcursor)
  38. window *win;
  39. int **newarea;
  40. int rows;
  41. int cols;
  42. position *newcursor;
  43. {
  44.     int i, j, ni, nj;
  45.  
  46.     /* Copy from the bottom up... */
  47.     newcursor->x=0;
  48.     for ( i=win->rows, ni=rows; i && ni; --i, --ni ) {
  49.         if ( win->cursor.x == i ) {
  50.             if ( (newcursor->x=(i+rows-win->rows)) < 1 )
  51.                 newcursor->x=1;
  52.         }
  53.         for ( j=0, nj=0; (j<win->cols) && (nj<cols); ++j, ++nj )
  54.             newarea[ni-1][nj]=win->videomem[i-1][j];
  55.     }
  56.     if ( ! newcursor->x )    /* We never reached the old cursor */
  57.         newcursor->x=1;
  58.     newcursor->y=(win->cursor.y > cols ? cols : win->cursor.y);
  59. }
  60.  
  61. /* This function adds a character to the video memory at the cursor position */
  62. void add_video(win, c)
  63. window *win;
  64. char c;
  65. {
  66.     win->videomem[win->cursor.x - 1][win->cursor.y - 1] = (int)c;
  67.     win->videomem[win->cursor.x - 1][win->cursor.y - 1] |= 
  68.                         (((int)win->textattr)<<8);
  69. }
  70.  
  71. /* This function returns a character from video at a specific position */
  72. int get_video(win, x, y)
  73. window *win;
  74. int x, y;
  75. {
  76.     return(win->videomem[x-1][y-1]);
  77. }
  78.  
  79. /* This function sets a character position in video memory */
  80. void put_video(c, win, x, y)
  81. int c;
  82. window *win;
  83. int x, y;
  84. {
  85.     win->videomem[x-1][y-1]=c;
  86. }
  87.  
  88. /* This function returns the array index of the end of the specified line
  89.    in the specified window.  lineno should start as 1 for the first line.
  90. */
  91. static int video_eol(win, lineno)
  92. window *win;
  93. int lineno;
  94. {
  95.     int eol=(-1), j;
  96.  
  97.     for ( j=0; j<win->cols; ++j ) {
  98.         if ( (win->videomem[lineno-1][j]&0xFF) != 0 )
  99.             eol=j;
  100.     }
  101.     ++eol;
  102.     return(eol);
  103. }
  104.  
  105. /* This function copies a specified section of video memory to a buffer */
  106. /* x1 is the first line, x2 is the second line, y1 is the y on the first
  107.    line, and y2 is the y on the last line.
  108. */
  109. void getsel_video(win, buf, maxlen, x1, x2, y1, y2)
  110. window *win;
  111. char *buf;
  112. int maxlen;
  113. int x1, x2;
  114. int y1, y2;
  115. {
  116.     int l=0, i, j, eol, eos;
  117.  
  118.     --maxlen;    /* Account for trailing null */
  119.     for ( i=(x1-1); (i<x2 && l<maxlen); ++i ) {
  120.         eol=video_eol(win, i+1);
  121.         if ( i == (x1-1) ) {
  122.             j=(y1-1);
  123.             eos=eol;
  124.         } else
  125.             j=0;
  126.         if ( i == (x2-1) )
  127.             eos=((y2-1) < eol ? (y2-1) : eol);
  128.         for ( ; j<eos; ++j ) {
  129.             if ( win->videomem[i][j] == 0 )
  130.                 *(buf++) = ' ';
  131.             else
  132.                 *(buf++) = win->videomem[i][j];
  133.             ++l;
  134.         }
  135.         if ( l<maxlen && j >= eol ) {
  136.             *(buf++) = '\r';
  137.             ++l;
  138.         }
  139.     }
  140.     *buf='\0';
  141.     return;
  142. }
  143.  
  144. /* This function clears the SELECTED bit in a whole window */
  145. void clrsel_video(win)
  146. window *win;
  147. {
  148.     int i, j;
  149.  
  150.     for ( i=0; i<win->rows; ++i ) {
  151.         for ( j=0; j<win->cols; ++j ) {
  152.             if ( ((win->videomem[i][j]>>8)&SELECTED) == SELECTED )
  153.                 win->videomem[i][j] &= ~(SELECTED<<8);
  154.         }
  155.     }
  156. }
  157.  
  158. /* This function erases a specified section of video memory */
  159. void erase_video(win, x1, x2, y1, y2)
  160. window *win;
  161. int x1, x2;
  162. int y1, y2;
  163. {
  164.     int i, j;
  165.  
  166.     for ( i=(x1-1); i<x2; ++i ) {
  167.         for ( j=(y1-1); j<y2; ++j )
  168.             win->videomem[i][j] = 0;
  169.     }
  170.     return;
  171. }
  172.  
  173. /* This function "scrolls" video memory forward */
  174. void scroll_video(win, numlines)
  175. window *win;
  176. int numlines;
  177. {
  178.     int i, n, *tmp;
  179.  
  180.     /* Don't scroll memory if cursor is outside of scroll region */
  181.     if ( win->cursor.x > win->scr_lower )
  182.         return;
  183.  
  184.     /* Otherwise, scroll away! */
  185.     for ( i=0; i<numlines; ++i ) {
  186.         /* Clear out the line that has been scrolled off the edge */
  187.         tmp=win->videomem[win->scr_upper-1];
  188.         for ( n=0; n<win->cols; ++n )
  189.             tmp[n]=0;
  190.  
  191.         /* Now perform the scroll */
  192.         for ( n=(win->scr_upper-1); n<(win->scr_lower-1); ++n )
  193.             win->videomem[n]=win->videomem[n+1];
  194.         win->videomem[n]=tmp;
  195.     }
  196.     /* That's it! */
  197.     return;
  198. }
  199.  
  200. /* This function "scrolls" video memory backward */
  201. void revscroll_video(win, numlines)
  202. window *win;
  203. int numlines;
  204. {
  205.     int i, n, *tmp;
  206.  
  207.     /* Don't scroll memory if cursor is outside of scroll region */
  208.     if ( win->cursor.x < win->scr_upper )
  209.         return;
  210.  
  211.     /* Otherwise, scroll away! */
  212.     for ( i=0; i<numlines; ++i ) {
  213.         /* Clear out the line that has been scrolled off the edge */
  214.         tmp=win->videomem[win->scr_lower-1];
  215.         for ( n=0; n<win->cols; ++n )
  216.             tmp[n]=0;
  217.  
  218.         /* Now perform the scroll */
  219.         for ( n=(win->scr_lower-1); n>(win->scr_upper-1); --n )
  220.             win->videomem[n]=win->videomem[n-1];
  221.         win->videomem[n]=tmp;
  222.     }
  223.     /* That's it! */
  224.     return;
  225. }
  226.  
  227. /* This function inserts nulls in a line, shifting everything right */
  228. void rshift_video(win, numcols)
  229. window *win;
  230. int numcols;
  231. {
  232.     int i;
  233.  
  234.     for ( i=(win->cols-1); i > (win->cursor.y-1); --i ) {
  235.         if ( (i-numcols) >= 0 )
  236.             win->videomem[win->cursor.x-1][i] = 
  237.                 win->videomem[win->cursor.x-1][i-numcols];
  238.         else
  239.             win->videomem[win->cursor.x-1][i] = 0;
  240.     }
  241. }
  242.  
  243. int check_attr(pixel, lastattr, currattr)
  244. int pixel;
  245. int lastattr;
  246. unsigned char *currattr;
  247. {
  248.     unsigned char change;
  249.     unsigned char selected, reversed;
  250.     unsigned char ohighlight, highlight;
  251.  
  252.     /* Thanks to Dan Dorough for the XOR code */
  253.     change = ((lastattr ^ pixel)>>8);
  254.     if ( change ) {
  255.         if ( change&SELECTED ) {
  256.             if ( change&REVERSE ) {
  257.                 if ( (*currattr)&REVERSE )
  258.                     *currattr &= ~REVERSE;
  259.                 else
  260.                     *currattr |= REVERSE;
  261.             }
  262.             if ( (*currattr)&SELECTED )
  263.                 *currattr &= ~SELECTED;
  264.             else
  265.                 *currattr |= SELECTED;
  266.             selected = ( (lastattr&SELECTED) ? 1 : 0 );
  267.             reversed = ( (lastattr&REVERSE) ? 1 : 0 );
  268.             ohighlight = ( selected ^ reversed );
  269.             selected = ( ((*currattr)&SELECTED) ? 1 : 0 );
  270.             reversed = ( ((*currattr)&REVERSE) ? 1 : 0 );
  271.             highlight = ( selected ^ reversed );
  272.             if ( ohighlight != highlight )
  273.                 vt_reverse(highlight);
  274.         }
  275.         else if ( change&REVERSE ) {
  276.             if ( (*currattr)&REVERSE ) {
  277.                 vt_reverse(0);
  278.                 *currattr &= ~REVERSE;
  279.             } else {
  280.                 vt_reverse(1);
  281.                 *currattr |= REVERSE;
  282.             }
  283.         }
  284.         if ( change&BOLD ) {
  285.             if ( (*currattr)&BOLD ) {
  286.                 vt_bold(0);
  287.                 *currattr &= ~BOLD;
  288.             } else {
  289.                 vt_bold(1);
  290.                 *currattr |= BOLD;
  291.             }
  292.         }
  293.         if ( change&UNDERLINE ) {
  294.             if ( (*currattr)&UNDERLINE ) {
  295.                 vt_underline(0);
  296.                 *currattr &= ~UNDERLINE;
  297.             } else {
  298.                 vt_underline(1);
  299.                 *currattr |= UNDERLINE;
  300.             }
  301.         }
  302.         if ( change&BLINK ) {
  303.             if ( (*currattr)&BLINK ) {
  304.                 vt_blink(0);
  305.                 *currattr &= ~BLINK;
  306.             } else {
  307.                 vt_blink(1);
  308.                 *currattr |= BLINK;
  309.             }
  310.         }
  311.     }
  312.     return(pixel);
  313. }
  314.  
  315. void paint_video(win)
  316. window *win;
  317. {
  318.     unsigned char change, on=NORMAL;
  319.     int i, j, oldattr=0;
  320.  
  321.     vt_setscroll(0,0);
  322.     vt_resetattr();
  323.     vt_goto(1+win->row_offset, 1);
  324.     for ( i=0; i<win->rows; ++i ) {
  325.         for ( j=0; j<win->cols; ++j ) {
  326.             if ( win->videomem[i][j]&0xFF ) {
  327.                 oldattr=check_attr(win->videomem[i][j],
  328.                                  oldattr, &on);
  329.                 printf("%c", (win->videomem[i][j]&0xFF));
  330.             } else {
  331.                 oldattr=0;
  332.                 if ( on != NORMAL ) {
  333.                     vt_resetattr();
  334.                     on=NORMAL;
  335.                 }
  336.                 printf(" ");
  337.             }
  338.         }
  339.         printf("\r");
  340.         vt_down(1);        /* This shouldn't cause scroll */
  341.     }
  342.     vt_setscroll(win->scr_upper+win->row_offset, 
  343.                     win->scr_lower+win->row_offset);
  344.     vt_goto(win->cursor.x+win->row_offset, win->cursor.y);
  345.     vt_update();
  346. }
  347.